package com.uiao.commons;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.validation.constraints.Null;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.realm.AuthenticatingRealm;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.util.ByteSource;

/**
 * 
 * 多Realm认证，为了保证安全，多个Realm的加密方式，数据库，表都可以不同。在这只设置加密和表不同。
 * 默认的认证策略是AtLeastOneSuccessfulStrategy 只要有一个Realm认证成功就登录成功
 * @author Administrator
 *
 */
public class SecondRealm extends AuthenticatingRealm {

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(
			AuthenticationToken token) throws AuthenticationException {

		SimpleAuthenticationInfo info = null;
		System.out.println("执行第二个的Realm");
		// 1.将token转换成UsernamePasswordToken
		UsernamePasswordToken upToken = (UsernamePasswordToken) token;
		// 2.获取用户名
		String username = upToken.getUsername();
		// 2.查询数据库
		try {
			Class.forName("com.mysql.jdbc.Driver");

			String url = "jdbc:mysql://localhost:3306/shiro?characterEncoding=utf-8";

			Connection conn = DriverManager.getConnection(url, "root", "123");

			String sql = "select * from seconduser where name = ?";
			PreparedStatement ps = conn.prepareStatement(sql);
			ps.setString(1, username);
			ResultSet resultSet = ps.executeQuery();

			if (resultSet.next()) {
				Object principal = username;

				Object credentials = resultSet.getString("password");

				String realmName = this.getName();

				// token中的密码进行盐值加密
				ByteSource salt = new ByteSource.Util().bytes(resultSet
						.getString("id"));
				// 封装数据库中获取的密码，进行MD5及盐值加密
				SimpleHash sh = new SimpleHash("SHA1", credentials, salt, 5);

				// 获取正确数据，具体的认证由shiro api来完成
				info = new SimpleAuthenticationInfo(principal, sh, salt,
						realmName);

			} else {
				throw new AuthenticationException();
			}

		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}

		return info;
	}

}
